package com.ysd.lis.service.lab.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.ysd.common.Result;
import com.ysd.lis.entity.SysOrgDepartment;
import com.ysd.lis.entity.lab.LabFeeItem;
import com.ysd.lis.entity.lab.LabRptGroup;
import com.ysd.lis.entity.lab.LabTatGrouprule;
import com.ysd.lis.entity.lab.LabTatNode;
import com.ysd.lis.mapper.lab.*;
import com.ysd.lis.mapper.sys.SysOrgDepartmentMapper;
import com.ysd.lis.request.lab.*;
import com.ysd.lis.service.lab.LabTatBaseruleDetailService;
import com.ysd.lis.service.lab.LabTatGroupruleService;
import com.ysd.lis.service.lab.LabTatNodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author cfz
 * @since 2024-10-30
 */
@Service
public class LabTatGroupruleServiceImpl extends ServiceImpl<LabTatGroupruleMapper, LabTatGrouprule> implements LabTatGroupruleService {
    @Autowired
    LabTatGroupruleMapper labTatGroupruleMapper;
    @Autowired
    LabTatGroupruleService labTatGroupruleService;
    @Autowired
    LabTatBaseruleMapper labTatBaseruleMapper;
    @Autowired
    LabTatBaseruleDetailService labTatBaseruleDetailService;
    @Autowired
    LabRptGroupMapper labRptGroupMapper;
    @Autowired
    LabFeeItemMapper labFeeItemMapper;
    @Autowired
    SysOrgDepartmentMapper sysOrgDepartmentMapper;
    @Autowired
    LabTatNodeService labTatNodeService;
    @Autowired
    LabTatNodeMapper labTatNodeMapper;


    @Override
    public Result findLabTatGroupruleList(LabTatGrouprule labTatGrouprule) {
        List<LabTatGrouprule> list = findLabTatGroupruleArray(labTatGrouprule);
        return Result.succ(1, "请求成功", list);
    }

    @Override
    public List<LabTatGrouprule> findLabTatGroupruleArray(LabTatGrouprule labTatGrouprule) {
        MPJLambdaWrapper<LabTatGrouprule> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.eq(LabTatGrouprule::getDelFlag, 0);
        queryWrapper.eq(StringUtils.isNotBlank(labTatGrouprule.getId()), LabTatGrouprule::getId, labTatGrouprule.getId());
        return labTatGroupruleMapper.selectList(queryWrapper);
    }

    @Override
    public Result findTatGroupruleDetails(LabTatGrouprule labTatGrouprule) {
        MPJLambdaWrapper<LabTatGrouprule> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.eq(LabTatGrouprule::getDelFlag, 0);
        if (StringUtils.isNotBlank(labTatGrouprule.getBaseruleNo())) {
            queryWrapper.eq(LabTatGrouprule::getBaseruleNo, labTatGrouprule.getBaseruleNo());
        }
        if (StringUtils.isNotBlank(labTatGrouprule.getBaseruleId())) {
            queryWrapper.eq(LabTatGrouprule::getBaseruleId, labTatGrouprule.getBaseruleId());
        }

        List<LabTatGrouprule> list = labTatGroupruleMapper.selectList(queryWrapper);
        List<String> rptGroups = list.stream().map(LabTatGrouprule::getRptGroup).distinct().collect(Collectors.toList());
        List<String> feeItems = list.stream().map(LabTatGrouprule::getFeeCode).distinct().collect(Collectors.toList());
        List<String> reqDepts = list.stream().map(LabTatGrouprule::getReqDept).distinct().collect(Collectors.toList());

        LabtatGroupruleSaveOrUpdateDto res = new LabtatGroupruleSaveOrUpdateDto();

        /*查询报告单元*/
        MPJLambdaWrapper<LabRptGroup> queryWrapperRptGroup = new MPJLambdaWrapper<>();
        queryWrapperRptGroup.eq(LabRptGroup::getDelFlag, 0);
        queryWrapperRptGroup.in(LabRptGroup::getRptGroup, rptGroups);
        List<LabRptGroup> rptGroupList = labRptGroupMapper.selectList(queryWrapperRptGroup);
        res.setRptGroupList(rptGroupList);

        /*查询收费项目*/
        MPJLambdaWrapper<LabFeeItem> queryWrapperFeeItem = new MPJLambdaWrapper<>();
        queryWrapperFeeItem.eq(LabFeeItem::getDelFlag, 0);
        queryWrapperFeeItem.in(LabFeeItem::getFeeCode, feeItems);
        List<LabFeeItem> feeItemList = labFeeItemMapper.selectList(queryWrapperFeeItem);
        res.setFeeItemList(feeItemList);

        /*查询申请课室*/
        MPJLambdaWrapper<SysOrgDepartment> queryWrapperReqDept = new MPJLambdaWrapper<>();
        queryWrapperReqDept.eq(SysOrgDepartment::getDelFlag, 0);
        queryWrapperReqDept.in(SysOrgDepartment::getCode, reqDepts);
        List<SysOrgDepartment> reqDeptList = sysOrgDepartmentMapper.selectList(queryWrapperReqDept);
        res.setDepartmentList(reqDeptList);

        /*时段分组*/
        Map<List<String>, List<LabTatGrouprule>> allData = list.stream().collect(Collectors.groupingBy(s -> Arrays.asList(s.getStartTime(), s.getEndTime())));
        List<TatGroupruleTimeSlotParam> timeSLotList = new ArrayList<>();
        for (Map.Entry<List<String>, List<LabTatGrouprule>> entry : allData.entrySet()) {
            TatGroupruleTimeSlotParam obj = new TatGroupruleTimeSlotParam();
            obj.setStartTime(entry.getKey().get(0));
            obj.setEndTime(entry.getKey().get(1));
            timeSLotList.add(obj);
        }
        timeSLotList = timeSLotList.stream().sorted(Comparator.comparing(TatGroupruleTimeSlotParam::getStartTime, Comparator.naturalOrder())).collect(Collectors.toList());
        res.setTimeSlotList(timeSLotList);
        return Result.succ(1, "成功", res);
    }

    @Override
    public Result addLabTatGrouprule(LabTatGrouprule labTatGrouprule) {
        int i = labTatGroupruleMapper.insert(labTatGrouprule);
        if (i > 0) {
            return Result.succ(1, "新增成功", labTatGrouprule);
        }
        return Result.fail("新增失败");
    }

    @Override
    public Result deleteLabTatGrouprule(LabTatGrouprule labTatGrouprule) {
        labTatGrouprule.setDelFlag(1);
        int i = labTatGroupruleMapper.updateById(labTatGrouprule);
        if (i > 0) {
            return Result.succ(1, "删除成功", labTatGrouprule);
        }
        return Result.fail("删除失败");
    }

    @Override
    public Result updateLabTatGrouprule(LabTatGrouprule labTatGrouprule) {
        int i = labTatGroupruleMapper.updateById(labTatGrouprule);
        if (i > 0) {
            return Result.succ(1, "更新成功", labTatGrouprule);
        }
        return Result.fail("更新失败");
    }

    /*保存组合*/
    @Override
    public Result saveOrUpdateGroupruleList(LabtatGroupruleSaveOrUpdateParam input) {
        if (BeanUtil.isEmpty(input.getLabTatBaserule())) {
            return Result.fail("基础组合为空");
        }
        if (CollectionUtils.isEmpty(input.getRptGroupList())) {
            return Result.fail("报告单元为空");
        }
        if (CollectionUtils.isEmpty(input.getFeeItemList())) {
            return Result.fail("申请项目为空");
        }
        if (CollectionUtils.isEmpty(input.getDepartmentList())) {
            return Result.fail("申请科室为空");
        }
        if (CollectionUtils.isEmpty(input.getTimeSlotList())) {
            return Result.fail("时间段为空");
        }
        /*先删除已有数据*/
        LambdaQueryWrapper<LabTatGrouprule> queryWrapperDelete = new LambdaQueryWrapper<>();
        queryWrapperDelete.eq(LabTatGrouprule::getBaseruleId, input.getLabTatBaserule().getId());
        labTatGroupruleMapper.delete(queryWrapperDelete);

        /*重新插入数据*/
        List<LabTatGrouprule> newGroupreleList = new ArrayList<>();
        for (LabRptGroup mRptGroup : input.getRptGroupList()) {
            for (LabFeeItem mFeeItem : input.getFeeItemList()) {
                for (SysOrgDepartment mReqDept : input.getDepartmentList()) {
                    for (TatGroupruleTimeSlotParam mTimeSlot : input.getTimeSlotList()) {
                        LabTatGrouprule obj = new LabTatGrouprule();
                        obj.setBaseruleId(input.getLabTatBaserule().getId());
                        obj.setBaseruleNo(input.getLabTatBaserule().getBaseruleNo());
                        obj.setBaseruleNa(input.getLabTatBaserule().getBaseruleNa());
                        obj.setEndTime(mTimeSlot.getEndTime());
                        obj.setFeeCode(mFeeItem.getFeeCode());
                        obj.setReqDept(mReqDept.getCode());
                        obj.setStartTime(mTimeSlot.getStartTime());
                        obj.setEndTime(mTimeSlot.getEndTime());
                        obj.setRptGroup(mRptGroup.getRptGroup());
                        newGroupreleList.add(obj);
                    }
                }
            }
        }

        boolean r = labTatGroupruleService.saveBatch(newGroupreleList);
        return r ? Result.succ(1, "成功", newGroupreleList) : Result.fail("保存失败");
    }

    /*验证是否需要TAT提醒*/
    @Override
    public Result validateIsTatTips(ValidateIsTatTipsParam input) {
        ValidateIsTatTipsDto res = validateIsTatTipsAction(input);
        return Result.succ(1, "成功", res);
    }

    @Override
    public ValidateIsTatTipsDto validateIsTatTipsAction(ValidateIsTatTipsParam input) {
        ValidateIsTatTipsDto res = new ValidateIsTatTipsDto();
        if (BeanUtil.isEmpty(input.getAnchorTime())) {
            res.setIsTip(false);
            res.setContentTip("锚点时间为空");
            return res;
        }

        /*反向*/
        MPJLambdaWrapper<LabTatNode> nodeQueryWrapper = new MPJLambdaWrapper<>();
        nodeQueryWrapper.eq(LabTatNode::getDelFlag, 0);
        nodeQueryWrapper.eq(LabTatNode::getNodeStartNo, input.getNodeStart());
        nodeQueryWrapper.eq(LabTatNode::getNodeEndNo, input.getNodeEnd());
        nodeQueryWrapper.eq(LabTatNode::getIsEnable, 1);
        String sql = "SELECT 1 FROM LAB_TAT_BASERULE_DETAIL t2 WHERE t2.DEL_FLAG=0 AND 1=1 ";
        String sqlWhere1 = StringUtils.isNotBlank(input.getPatType()) ? "AND t2.PAT_TYPE='" + input.getPatType() + "' " : " ";/*病人类型*/
        String sqlWhere2 = BeanUtil.isNotEmpty(input.getIsUrgent()) ? "AND t2.IS_URGENT=" + input.getIsUrgent() + " " : " ";/*是否紧急*/
        String sqlWhere3 = StringUtils.isNotBlank(input.getSampleType()) ? "AND t2.SAMPLE_TYPE='" + input.getSampleType() + "' " : " ";/*样本类型*/
        String sqlWhere4 = StringUtils.isNotBlank(input.getBarcodeNo()) ? "AND t2.BARCODE_TYPE='" + input.getBarcodeNo() + "' " : " ";/*分管类别*/

        /*起始节点条件*/
        String sqlWhere5_1 = StringUtils.isNotBlank(input.getRptGroup()) ? " AND t3.RPT_GROUP='" + input.getRptGroup() + "' " : "";
        String sqlWhere5_2 = StringUtils.isNotBlank(input.getFeeCode()) ? " AND t3.FEE_CODE='" + input.getFeeCode() + "' " : "";
        String sqlWhere5_3 = StringUtils.isNotBlank(input.getReqDept()) ? " AND t3.REQ_DEPT='" + input.getReqDept() + "' " : "";
        String sqlWhere5 = "AND exists (SELECT 1 FROM LAB_TAT_GROUPRULE t3 WHERE t2.TAT_BASERULE_ID=t3.BASERULE_ID AND t3.DEL_FLAG=0 " + sqlWhere5_1 + " " + sqlWhere5_2 + " " + sqlWhere5_3 + ")";
        sql += sqlWhere1;
        sql += sqlWhere2;
        sql += sqlWhere3;
        sql += sqlWhere4;
        sql += sqlWhere5;
        nodeQueryWrapper.exists(sql);

        List<LabTatNode> listNodes = labTatNodeMapper.selectList(nodeQueryWrapper);
        if (CollectionUtils.isEmpty(listNodes)) {
            res.setIsTip(false);
            res.setContentTip("没有可用的规则");
            return res;
        }

        // 定义时间格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 解析锚点时间字符串为 LocalDateTime
        LocalDateTime anchorTime = LocalDateTime.parse(input.getAnchorTime(), formatter);
        // 获取当前时间
        LocalDateTime currentTime = input.getIsGetCurDateTime() ? LocalDateTime.now() : LocalDateTime.parse(input.getAnchorTimeEnd(), formatter);

        // 计算时间差并转换为分钟
        long minutesDifference = Duration.between(anchorTime, currentTime).toMinutes();

        boolean resIsTips = false;
        String contentTips = "";
        for (LabTatNode m : listNodes) {
            if (BeanUtil.isNotEmpty(m.getMinTime()) && minutesDifference < m.getMinTime() && m.getMinTime() > 0) {
                resIsTips = true;
                contentTips = m.getTatNodeNa() + ",小于TAT规定的最小时间:[" + m.getMinTime() + "]分钟";
                break;
            }
            if (BeanUtil.isNotEmpty(m.getMaxTime()) && minutesDifference > m.getMaxTime() && m.getMaxTime() > 0) {
                resIsTips = true;
                contentTips = m.getTatNodeNa() + ",大于TAT规定的最大时间:[" + m.getMinTime() + "]分钟";
                break;
            }

            if (BeanUtil.isNotEmpty(m.getPrewarnTime()) && minutesDifference > m.getPrewarnTime() && m.getPrewarnTime() > 0) {
                resIsTips = true;
                contentTips = "TAT预警:" + m.getTatNodeNa() + ",时间:[" + m.getPrewarnTime() + "]分钟";
                break;
            }

            if (BeanUtil.isNotEmpty(m.getWarnTime()) && minutesDifference > m.getWarnTime() && m.getWarnTime() > 0) {
                resIsTips = true;
                contentTips = "TAT警告:" + m.getTatNodeNa() + ",时间:[" + m.getWarnTime() + "]分钟";
                break;
            }
        }

        res.setIsTip(resIsTips);
        res.setContentTip(contentTips);
        return res;
    }
}
